from flask import g, redirect, url_for, render_template, abort, request, jsonify, current_app

from info import db
from info.constants import USER_COLLECTION_MAX_NEWS, QINIU_DOMIN_PREFIX, USER_FOLLOWED_MAX_COUNT
from info.models import tb_user_collection, News, Category, User
from info.modules.user import user_blu
from info.utils.common import file_upload
# 2使用蓝图注册路由
# 个人中心
from info.utils.common import user_login_data
from info.utils.response_code import RET, error_map


# 个人中心界面，模板渲染个人中心和数据传递给模板渲染
@user_blu.route('/user_info')
@user_login_data
def user_info():
    # 判断用户是否登录
    user = g.user
    if not user:  # 如果没有登录跳转到首页界面
        return redirect(url_for('home.index'))
    return render_template('news/user.html', user=user.to_dict())


# 个人资料显示
@user_blu.route('/base_info', methods=['POST', 'GET'])
@user_login_data
def base_info():
    # 判断用户是否登录
    user = g.user
    if not user:  # 如果没有登录,拒绝访问
        return abort(403)
    if request.method == 'GET':
        return render_template('news/user_base_info.html', user=user.to_dict())
    # POST,个人资料界面,需要三个参数，个性签名，昵称，性别
    # 获取参数
    signature = request.json.get('signature')
    nick_name = request.json.get('nick_name')
    gender = request.json.get('gender')
    # 校验参数
    if not all([signature, nick_name, gender]):
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])
    if gender not in ["MAN", "WOMAN"]:
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])
    # 修改用户模型
    user.signature = signature
    user.nick_name = nick_name
    user.gender = gender

    # JSON返回
    # data需要传递进去，作为页面的刷新
    return jsonify(errno=RET.OK, errmsg=error_map[RET.OK], data=user.to_dict())


# 定义修改头像的路由
@user_blu.route('/pic_info', methods=['POST', 'GET'])
@user_login_data
def pic_info():
    user = g.user
    if not user:  # 如果没有登录,拒绝访问
        return abort(403)
    if request.method == 'GET':
        return render_template('news/user_pic_info.html', user=user.to_dict())
    # POST
    # 获取参数
    file = request.files.get('avatar')

    try:
        img_bytes = file.read()
        # 读取上传文件的格式都是二进制形式
        # 一般上传的文件都是会保存在一个文件服务器中进行管理，只需要获取链接即可
        try:
            file_name = file_upload(img_bytes)
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.THIRDERR, errmsg=error_map[RET.THIRDERR])

        user.avatar_url = file_name

    except Exception as e:
        current_app.logger.error(e)

        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])
    # 将上传的文件保存到七牛云
    # 更新用户模型，设置头像链接
    # 返回json结果
    return jsonify(errno=RET.OK, errmsg=error_map[RET.OK], data=user.to_dict())


# 显示我的收藏
@user_blu.route('/collection')
@user_login_data
def collection():
    user = g.user
    if not user:  # 如果没有登录,拒绝访问
        return abort(403)
    p = request.args.get('p', 1)
    try:
        p = int(p)
    except Exception as e:
        current_app.logger.error(e)
        return abort(403)
    try:
        pn = user.collection_news.order_by(tb_user_collection.c.create_time.desc()).paginate(p,
                                                                                             USER_COLLECTION_MAX_NEWS)
    except Exception as e:
        current_app.logger.error(e)
    data = {
        "news_list": [news.to_dict() for news in pn.items],
        "cur_page": p,
        "total_page": pn.pages
    }
    return render_template('news/user_collection.html', data=data)


# 修改密码
@user_blu.route('/pass_info', methods=['POST', 'GET'])
@user_login_data
def pass_info():
    user = g.user
    if not user:
        return abort(403)
    if request.method == 'GET':
        # 静态页面不需要返回
        return render_template('news/user_pass_info.html')
    # post
    # 获取参数－旧的密码，新密码，确认密码
    old_password = request.json.get('old_password')
    new_password = request.json.get('new_password')
    # 校验参数
    if not all([old_password, new_password]):
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])
    # 校验旧的密码
    # 校验密码
    if not user.check_password(old_password):
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])
    # 修改用户模型
    user.password = new_password

    return jsonify(errno=RET.OK, errmsg=error_map[RET.OK])


# 发布新闻
@user_blu.route('/news_release', methods=['POST', 'GET'])
@user_login_data
def news_release():
    user = g.user
    if not user:
        return abort(403)
    if request.method == 'GET':
        # 查询所有的分类传入模板
        try:
            categories = Category.query.all()
        except Exception as e:
            current_app.logger.error(e)
            return abort(403)
        # 删除最新
        if len(categories):
            categories.pop(0)
        return render_template('news/user_news_release.html', categories=categories)
    # POST方法
    # 获取参数
    title = request.form.get('title')
    digest = request.form.get('digest')
    category_id = request.form.get('category_id')
    content = request.form.get('content')
    if not all([title, digest, category_id, content]):
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])
    # 通过分类id去查询分类种类
    try:
        category_id = int(category_id)
        category = Category.query.get(category_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])
    # 如果没有这个分类则返回参数不足
    if not category:
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])
    # 生成新闻模型
    news = News()
    news.title = title
    news.digest = digest
    news.content = content
    news.category_id = category_id
    news.user_id = user.id
    news.source = "个人发布新闻"
    news.status = 1
    try:
        img_bytes = request.files.get('index_image').read()
        try:
            file_name = file_upload(img_bytes)
            news.index_image_url = QINIU_DOMIN_PREFIX + file_name
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.THIRDERR, errmsg=error_map[RET.THIRDERR])
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])
    # 添加用户模型
    db.session.add(news)
    return jsonify(errno=RET.OK, errmsg=error_map[RET.OK])


# 新闻列表的展示
@user_blu.route('/news_list')
@user_login_data
def news_list():
    user = g.user
    if not user:
        return abort(403)
    # 查询当前用户发布的新闻
    p = request.args.get('p', 1)
    try:
        p = int(p)
    except Exception as e:
        current_app.logger.error(e)
        return abort(403)
    try:
        pn = user.news_list.order_by(News.create_time.desc()).paginate(p, USER_COLLECTION_MAX_NEWS)
    except Exception as e:
        current_app.logger.error(e)
    data = {
        "news_list": [news.to_review_dict() for news in pn.items],
        "cur_page": p,
        "total_page": pn.pages
    }
    news_list = [news for news in user.news_list]

    return render_template('news/user_news_list.html', news_list=news_list, data=data)


# 显示关注列表
@user_blu.route('/user_follow')
@user_login_data
def user_follow():
    user = g.user
    if not user:  # 如果没有登录,拒绝访问
        return abort(403)
    p = request.args.get('p', 1)
    try:
        p = int(p)
    except Exception as e:
        current_app.logger.error(e)
        return abort(403)
    pn = None
    try:
        pn = user.followed.paginate(p,
                                    USER_COLLECTION_MAX_NEWS)
    except Exception as e:
        current_app.logger.error(e)
    data = {
        "user_list": [user.to_dict() for user in pn.items],
        "cur_page": p,
        "total_page": pn.pages
    }

    return render_template('news/user_follow.html', data=data)


# 定义跳转到关注人信息
@user_blu.route('/other<int:user_id>')
def other(user_id):
    # 获取参数
    user_id = request.args.get('user_id')
    p = request.args.get('p')
    # 校验参数
    if not all([user_id,p]):
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])
    # 通过user_id去查询到这个用户
    try:
     user = User.query.get(user_id)
    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg=error_map[RET.DBERR])
    try:
        pn = user.news_list.order_by(News.create_time.desc()).paginate(p, USER_COLLECTION_MAX_NEWS)
    except BaseException as e:
        current_app.logger.error(e)

    data = {
        "news_list":[news.to_review_dict() for news in pn.items],
        "cur_page": p,
        "total_page": pn.pages
    }
    return render_template('news/other.html',user=user,data = data)


